using Crux.Core.Dapper.SqlGenerator;
using Crux.Core.Data;

namespace Crux.Core.Dapper;
/// <summary>
/// 
/// </summary>
/// <typeparam name="TContext"></typeparam>
public interface IQueryRepository<out TContext>
    where TContext : DapperContext
{
    /// <summary>
    ///
    /// </summary>
    TContext Context { get; }
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    SqlGenerator<TEntity> GetSqlGenerator<TEntity>(Action<SqlGenerator<TEntity>>? configure = null) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <returns></returns>
    bool Any<TEntity>(Expression<Func<TEntity, bool>> predicate, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <param name="predicate"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<bool> AnyAsync<TEntity>(Expression<Func<TEntity, bool>> predicate, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null, CancellationToken cancellationToken = default) where TEntity : class;
    /// <summary>
    /// /
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="id"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    TEntity? Find<TEntity>(object id, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null, params Expression<Func<TEntity, object>>[] includes) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="id"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <param name="cancellationToken"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    Task<TEntity?> FindAsync<TEntity>(object id, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null, CancellationToken cancellationToken = default, params Expression<Func<TEntity, object>>[] includes) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="predicate"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    TEntity? FirstOrDefault<TEntity>(Expression<Func<TEntity, bool>> predicate, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null, params Expression<Func<TEntity, object>>[] includes) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="predicate"></param>
    /// <param name="expr"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    TEntity? FirstOrDefault<TEntity>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> expr, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null, params Expression<Func<TEntity, object>>[] includes) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="predicate"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <param name="cancellationToken"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    Task<TEntity?> FirstOrDefaultAsync<TEntity>(Expression<Func<TEntity, bool>> predicate, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null, CancellationToken cancellationToken = default, params Expression<Func<TEntity, object>>[] includes) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="predicate"></param>
    /// <param name="expr"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <param name="cancellationToken"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    Task<TEntity?> FirstOrDefaultAsync<TEntity>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>> expr, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null, CancellationToken cancellationToken = default, params Expression<Func<TEntity, object>>[] includes) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="predicate"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <returns></returns>
    int Count<TEntity>(Expression<Func<TEntity, bool>> predicate, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="predicate"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<int> CountAsync<TEntity>(Expression<Func<TEntity, bool>> predicate, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null, CancellationToken cancellationToken = default) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="predicate"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <returns></returns>
    long LongCount<TEntity>(Expression<Func<TEntity, bool>> predicate, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="predicate"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="configure"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<long> LongCountAsync<TEntity>(Expression<Func<TEntity, bool>> predicate, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null,
        CancellationToken cancellationToken = default) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="sql"></param>
    /// <param name="parameters"></param>
    /// <returns></returns>
    IEnumerable<TEntity> SqlQueryRaw<TEntity>(string sql, object? parameters = null);
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <param name="sql"></param>
    /// <param name="parameters"></param>
    /// <param name="cancellationToken"></param>
    /// <returns></returns>
    Task<IEnumerable<TEntity>> SqlQueryRawAsync<TEntity>(string sql, object? parameters = null, CancellationToken cancellationToken = default);
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    IEnumerable<TEntity> Query<TEntity>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>>? expr = null, OrderExpression<TEntity>? orderExpression = null, uint limit = 0, uint offset = 0, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null, params Expression<Func<TEntity, object>>[] includes) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <returns></returns>
    Task<IEnumerable<TEntity>> QueryAsync<TEntity>(Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, object>>? expr = null, OrderExpression<TEntity>? orderExpression = null, uint limit = 0, uint offset = 0, bool ignoreFilter = false, Action<SqlGenerator<TEntity>>? configure = null, CancellationToken cancellationToken = default, params Expression<Func<TEntity, object>>[] includes) where TEntity : class;
    /// <summary>
    ///
    /// </summary>
    /// <param name="timeout"></param>
    /// <returns></returns>
    IQueryRepository<TContext> SetTimeout(in int timeout);
    /// <summary>
    /// 查询分页数据（非立即返回结果）
    /// </summary>
    /// <param name="where">条件</param>
    /// <param name="orderExpression"></param>
    /// <param name="expr"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="option"></param>
    /// <param name="configure"></param>
    /// <param name="includes"></param>
    /// <returns>查询分页数据</returns>
    Pageable<TEntity> GetByPage<TEntity>(Expression<Func<TEntity, bool>> where, OrderExpression<TEntity> orderExpression, Expression<Func<TEntity, object>>? expr = null, bool ignoreFilter = false, PageOption option = default, Action<SqlGenerator<TEntity>>? configure = null, params Expression<Func<TEntity, object>>[] includes) where TEntity : class;
    /// <summary>
    /// 查询分页数据（非立即返回结果）
    /// </summary>
    /// <param name="where">条件</param>
    /// <param name="orderExpression"></param>
    /// <param name="expr"></param>
    /// <param name="ignoreFilter"></param>
    /// <param name="option">option</param>
    /// <param name="configure"></param>
    /// <param name="cancellationToken"></param>
    /// <param name="includes"></param>
    /// <returns>查询分页数据</returns>
    Task<Pageable<TEntity>> GetByPageAsync<TEntity>(Expression<Func<TEntity, bool>> where, OrderExpression<TEntity> orderExpression, Expression<Func<TEntity, object>>? expr = null, bool ignoreFilter = false,
        PageOption option = default, Action<SqlGenerator<TEntity>>? configure = null, CancellationToken cancellationToken = default, params Expression<Func<TEntity, object>>[] includes) where TEntity : class;
}